#ifndef HAS_PTR_H
#define HAS_PTR_H

#include <string>

class HasPtr {
    friend void swap(HasPtr&, HasPtr&);
public:
    HasPtr(const std::string &s = new string()) :
        ps(new string(s)), i(0) { }
    HasPtr(const HasPtr&);
    HasPtr& operator =(const HasPtr &rhs);
    HasPtr& operator =(HasPtr rhs);
    ~HasPtr() { delete ps; }  // 合成的析构函数不会 delete 一个指针数据成员,需要手动释放
private:
    std::string *ps;
    int i;
};

inline
void swap(HasPtr &lhs, HasPtr &rhs)
{
    using std::swap;
    swap(lhs.ps, rhs.ps);   // 交换指针而不是 string 数据
    swap(lhs.i, rhs.i);     // 交换 int 数据成员
}

// 注意 rhs 是按值传递的,意味着 HasPtr 的拷贝构造函数将右侧运算对象中的 string 拷贝到 rhs
HasPtr& HasPtr::operator =(HasPtr rhs)
{
    // 交换左侧运算对象和局部变量 rhs 的内容
    swap(*this, rhs);   // rhs 现在指向本对象曾经使用的内存
    return *this;   // rhs 被销毁,从而 delete 了 rhs 中的指针
}

#endif // HAS_PTR_H
